package cn.huiyunche.bms.backend.service;

import cn.huiyunche.bms.backend.bo.ReceivableFeeDetailorTempBO;
import cn.huiyunche.bms.backend.constant.AutoConfConstant;
import cn.huiyunche.bms.backend.enums.BillStatusEnum;
import cn.huiyunche.bms.backend.enums.PayeeStatusEnum;
import cn.huiyunche.bms.backend.query.BmsReceivableBillConditions;
import cn.huiyunche.bms.backend.query.SServiceOrderConditions;
import cn.huiyunche.bms.backend.util.PoiUtil;
import cn.huiyunche.bms.backend.util.UniquenessUtil;
import cn.huiyunche.bms.base.mapper.*;
import cn.huiyunche.bms.base.model.*;
import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.HttpRequestUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Felix on 2017/7/6 9527.
 */
@Service
public class ReceivableServiceImpl implements ReceivableService{
    @Autowired
    private BmsReceivableFeeDetailTempMapper tempMapper;
    @Autowired
    private SServiceOrderMapper sOrderMapper;
    @Autowired
    private SOrderMapper orderMapper;
    @Autowired
    private BmsReceivableBillMapper billMapper;
    @Autowired
    private BmsReceivableFeeDetailMapper feeDetailMapper;
    @Autowired
    private AreaService areaService;
    @Autowired
    private AutoConfConstant autoConfConstant;

    private static final Logger LOGGER = LoggerFactory.getLogger(ReceivableServiceImpl.class);

    @Override
    public Map<String, Object> selectReceivableByConditions(PageVo pageVo, BmsReceivableBillConditions conditions) throws Exception {
        LOGGER.info("ReceivableServiceImpl.selectReceivableByConditions params : {}, {}", pageVo, conditions);
        Map<String, Object> map = new HashMap<>();
        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " id DESC";
        }
        BmsReceivableBillExample example = new BmsReceivableBillExample();
        BmsReceivableBillExample.Criteria criteria = example.createCriteria();
        if (conditions.getConsignorId() != null) {
            criteria.andConsignorIdEqualTo(conditions.getConsignorId());
        }
        if (StringUtils.isNotBlank(conditions.getBillCode())) {
            criteria.andBillCodeEqualTo(conditions.getBillCode());
        }
        if (StringUtils.isNotBlank(conditions.getBillStatus())) {
            criteria.andBillStatusEqualTo(conditions.getBillStatus());
        }
        if (StringUtils.isNotBlank(conditions.getUnBillStatus())) {
            criteria.andBillStatusNotEqualTo(conditions.getUnBillStatus());
        }
        if (StringUtils.isNotBlank(conditions.getPayeeStatus())) {
            criteria.andPayeeStatusEqualTo(conditions.getPayeeStatus());
        }
        if (conditions.getBillDateStart() != null && conditions.getBillDateEnd() != null) {
            criteria.andBillDateBetween(conditions.getBillDateStart(), conditions.getBillDateEnd());
        }else if (conditions.getBillDateStart() != null && conditions.getBillDateEnd() == null){
            criteria.andBillDateGreaterThanOrEqualTo(conditions.getBillDateStart());
        }else if (conditions.getBillDateStart() == null && conditions.getBillDateEnd() != null){
            criteria.andBillDateLessThanOrEqualTo(conditions.getBillDateEnd());
        }
        if (null != pageVo) {
            pageVo.setTotalRecord(billMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }
        List<BmsReceivableBill> list = billMapper.selectByExample(example);
        List<SServiceOrderWithReceivable> cust = sOrderMapper.selectConsignorName();
        map.put("list", list);
        map.put("cust", cust);
        if (null != pageVo) {
            map.put("page", pageVo);
        }
        return map;
    }

    @Override
    public Map<String, Object> selectServiceOrderByConditions(PageVo pageVo, SServiceOrderConditions conditions) throws Exception {
        LOGGER.info("ReceivableServiceImpl.selectServiceOrderByConditions params : {}, {}", pageVo, conditions);
        Map<String, Object> map = new HashMap<>();
        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " so.id DESC";
        }

        Map<String, Object> conMap = new HashMap<>();
        conMap.put("companyId", conditions.getConsignorId());
        conMap.put("status", conditions.getStatus());
        conMap.put("departProvinceCode", conditions.getDepartProvinceCode());
        conMap.put("departCityCode", conditions.getDepartCityCode());
        conMap.put("departCountyCode", conditions.getDepartCountyCode());
        conMap.put("receiptProvinceCode", conditions.getReceiptProvinceCode());
        conMap.put("receiptCityCode", conditions.getReceiptCityCode());
        conMap.put("receiptCountyCode", conditions.getReceiptCountyCode());
        conMap.put("createTimeEnd", conditions.getCreateTimeEnd());
        conMap.put("createTimeStart", conditions.getCreateTimeStart());
        if (conditions.getOrderCodes() != null) {
            List<String> codes = Arrays.asList(conditions.getOrderCodes().split(" "));
            conMap.put("orderCodes", codes);
        }
        if (conditions.getOutOrderCodes() != null) {
            List<String> codes = Arrays.asList(conditions.getOutOrderCodes().split(" "));
            conMap.put("outOrderCodes", codes);
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(sOrderMapper.selectCountServiceOrderByConditions(conMap));
            conMap.put("limitStart", pageVo.getStartIndex());
            conMap.put("limitEnd", pageVo.getPageSize());
            conMap.put("orderByClause", orderByClause);
        }
        List<SServiceOrderWithReceivable> list = sOrderMapper.selectServiceOrderByConditions(conMap);
        map.put("list", list);
        List<SServiceOrderWithReceivable> cust = sOrderMapper.selectConsignorName();
        map.put("cust", cust);
        List<BArea> areaList = areaService.queryProvince();
        map.put("areaList", areaList);
        if (null != pageVo) {
            map.put("page", pageVo);
        }
        return map;
    }

    @Override
    @Transactional
    public String insertTemp(List orderIds) throws Exception {
        LOGGER.info("ReceivableServiceImpl.insertTemp params : {}, {}", orderIds);
        String versionNo = UniquenessUtil.generateUniquenessFlag("BR");
        if (orderIds.size()>0) {
            List<SServiceOrderWithReceivable> list = sOrderMapper.selectServiceOrder(orderIds);
            if (list.size()>0) {
                for (SServiceOrderWithReceivable ss : list){
                    BmsReceivableFeeDetailTemp temp = new BmsReceivableFeeDetailTemp();
                    BeanUtils.copyProperties(ss, temp);
                    temp.setVersionNo(versionNo);
                    temp.setFeeDate(ss.getCreateTime());
                    temp.setSettleCost(ss.getSysCost());
                    if (temp.getConsignorId()==null){
                        LOGGER.error("getConsignorId  must not be null");
                        throw new IllegalArgumentException("客户名称不能为空！");
                    }
                    //Todo
                    temp.setCarrierId(132);
                    temp.setCarrierName("中联新渠道");
                    tempMapper.insertSelective(temp);
                }
            }
        }
        return versionNo;
    }

    @Override
    public Map<String, Object> selectReceivableDetailTemp(String versionNo) throws Exception {
        LOGGER.info("ReceivableServiceImpl.selectReceivableDetailTemp params : {}, {}", versionNo);
        if (versionNo==null) {
            LOGGER.error("ReceivableServiceImpl.selectReceivableDetailTemp param versionNo must not be null ");
            throw new IllegalArgumentException("版本号不能为空");
        }
        Map<String, Object> map = new HashMap<>();
        List<SServiceOrderWithReceivable> list = tempMapper.selectListTemp(versionNo);
        if (list.size()>0) {
            map.put("list", list);
            SServiceOrderWithReceivable temp1 = tempMapper.selectSumCost(versionNo);
            SServiceOrderWithReceivable temp = new SServiceOrderWithReceivable();
            if (temp1 !=null)
            BeanUtils.copyProperties(temp1, temp);
            temp.setVersionNo(versionNo);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            temp.setComment(format.format(new Date()));
            map.put("cost", temp);
        }
        return map;
    }

    @Override
    public void createRece(String versionNo, String invoiceStatus, String username) throws Exception {
        List<SServiceOrderWithReceivable> tempList = tempMapper.selectListTemp(versionNo);
        HashSet<Integer> set = new HashSet<>();
        for(SServiceOrderWithReceivable temp : tempList) {
            set.add(temp.getConsignorId());
        }
        Iterator<Integer> it = set.iterator();
        while (it.hasNext()){
            Integer id = it.next();
            List<SServiceOrderWithReceivable> list = new ArrayList<>();
            for(SServiceOrderWithReceivable temp : tempList) {
                if (temp.getConsignorId().equals(id)){
                    list.add(temp);
                }
            }
            BmsReceivableBill bill = new BmsReceivableBill();
            String billCode = UniquenessUtil.generateUniquenessFlag("BR");
            bill.setBillCode(billCode);
            bill.setBillDate(new Date());
            bill.setConsignorId(list.get(0).getConsignorId());
            bill.setConsignorName(list.get(0).getConsignorName());
            bill.setPayerId(list.get(0).getConsignorId());
            bill.setPayerName(list.get(0).getConsignorName());
            //TODO 承接人收款人写死
            bill.setCarrierId(132);
            bill.setCarrierName("中联新渠道");
            bill.setPayeeId(132);
            bill.setPayeeName("中联新渠道");
            BigDecimal sysCost = new BigDecimal(0);
            for (SServiceOrderWithReceivable order: list){
                if (order.getSysCost()!=null)
                    sysCost = sysCost.add(new BigDecimal(order.getSysCost().toString()));
            }
            bill.setOrderCost(sysCost);
            BigDecimal alterCost = new BigDecimal(0);
            for (SServiceOrderWithReceivable order: list){
                if (order.getAlterCost()!=null)
                    alterCost = alterCost.add(new BigDecimal(order.getAlterCost().toString()));
            }
            bill.setAlterCost(alterCost);
            BigDecimal settleCost = new BigDecimal(0);
            for (SServiceOrderWithReceivable order: list){
                if (order.getSettleCost()!=null)
                    settleCost = settleCost.add(new BigDecimal(order.getSettleCost().toString()));
            }
            bill.setGoodsSum(BigDecimal.valueOf(list.size()));
            bill.setSettleCost(settleCost);
            bill.setBillStatus(BillStatusEnum.NOCHECK.getValue());
            bill.setInvoiceStatus(invoiceStatus);
            bill.setCreateUser(username);
            billMapper.insertSelective(bill);
            BmsReceivableBillExample example = new BmsReceivableBillExample();
            example.createCriteria().andBillCodeEqualTo(billCode);
            List<BmsReceivableBill> bills = billMapper.selectByExample(example);
            for(SServiceOrderWithReceivable temp : list){
                BmsReceivableFeeDetail detail = new BmsReceivableFeeDetail();
                detail.setBillId(bills.get(0).getId());
                BeanUtils.copyProperties(temp, detail);
                detail.setFeeSource("10");
                detail.setFeeTypeCode("40");
                detail.setFeeTypeName("运输费");
                detail.setCreateUser(username);
                feeDetailMapper.insertSelective(detail);
            }
        }
        BmsReceivableFeeDetailTempExample tempExample = new BmsReceivableFeeDetailTempExample();
        tempExample.createCriteria().andVersionNoEqualTo(versionNo);
        tempMapper.deleteByExample(tempExample);
    }

    @Override
    public Integer confirmBill(Integer billId, String invoiceStatus) throws Exception {
        BmsReceivableBill bill = new BmsReceivableBill();
        try {
            bill.setId(billId);
            if (!invoiceStatus.equals(""));
            bill.setInvoiceStatus(invoiceStatus);
            bill.setBillStatus(BillStatusEnum.CHECKED.getValue());
            billMapper.updateByPrimaryKeySelective(bill);
        } catch (Exception e) {
            LOGGER.error("ReceivableServiceImpl.confirmBill failed");
            throw new IllegalArgumentException("确认账单失败");
        }
        //账单放入单据池
        BmsReceivableBill bill1 = billMapper.selectByPrimaryKey(billId);
        String url = autoConfConstant.getOperation()+ "/api/bms/bill/addReceivableBill";
        Integer time = autoConfConstant.getOperationTime();
        Map<String, Object> map = new HashMap<>();
        map.put("receivableBillCode", bill1.getBillCode());
        String result = HttpRequestUtil.sendHttpPost(url, map, time);
        if (!Objects.equals(result, null)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            String msgCode = jsonObject.getString("messageCode");
            String msg = jsonObject.getString("message");
//            String data = jsonObject.getString("data");
            Boolean success = jsonObject.getBoolean("success");
            if (!success) {
                LOGGER.error("ReceivableServiceImpl addReceivableBill result error");
                throw new BusinessException(msgCode, msg);
            }else {
                LOGGER.info("ReceivableServiceImpl addReceivableBill result success");
            }
        }
        return null;
    }

    @Override
    public Map<String, Object> selectReceivableDetailByConditions(PageVo pageVo, Integer billId) throws Exception {
        LOGGER.info("ReceivableServiceImpl.selectReceivableDetailByConditions params : {}, {}", pageVo, billId);
        Map<String, Object> map = new HashMap<>();
        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " id DESC";
        }
        Map<String, Object> conMap = new HashMap<>();
        conMap.put("billId", billId);
        if (null != pageVo) {
            pageVo.setTotalRecord(feeDetailMapper.selectListDetailCount(conMap));
            conMap.put("limitStart", pageVo.getStartIndex());
            conMap.put("limitEnd", pageVo.getPageSize());
            conMap.put("orderByClause", orderByClause);
        }
        List<SServiceOrderWithReceivable> list = feeDetailMapper.selectListDetail(conMap);
        BmsReceivableBill bill = billMapper.selectByPrimaryKey(billId);
        map.put("bill", bill);
        map.put("list", list);
        if (null != pageVo) {
            map.put("page", pageVo);
        }
        return map;
    }

    @Override
    public Integer updateReceivableDetailTemp(ReceivableFeeDetailorTempBO bo, BindingResult br) throws Exception {
        LOGGER.info("ReceivableServiceImpl.updateReceivableDetailTemp params : {}, {}", bo, br);
        //验证表单
        verificationForm(br);
        BmsReceivableFeeDetailTemp temp = new BmsReceivableFeeDetailTemp();
        BeanUtils.copyProperties(bo, temp);
        return tempMapper.updateByPrimaryKeySelective(temp);
    }

    @Override
    public Integer updateReceivableDetail(ReceivableFeeDetailorTempBO bo, BindingResult br) throws Exception {
        LOGGER.info("ReceivableServiceImpl.updateReceivableDetail params : {}, {}", bo, br);
        //验证表单
        verificationForm(br);
        BmsReceivableFeeDetail detail = new BmsReceivableFeeDetail();
        BeanUtils.copyProperties(bo, detail);
        feeDetailMapper.updateByPrimaryKeySelective(detail);
        BmsReceivableFeeDetail feeDetail = feeDetailMapper.selectByPrimaryKey(detail.getId());
        return sumBillCost(feeDetail.getBillId());
    }

    @Override
    public Integer deleteReceivable(List<Integer> ids) throws Exception {
        LOGGER.info("ReceivableServiceImpl.deleteReceivable params : {}, {}", ids);
        if (ids.size()<=0) {
            LOGGER.error("ReceivableServiceImpl.deleteReceivable param id must not be null ");
            throw new IllegalArgumentException("id不能为空");
        }
        for (Integer id : ids){
            billMapper.deleteByPrimaryKey(id);
            BmsReceivableFeeDetailExample example = new BmsReceivableFeeDetailExample();
            example.createCriteria().andBillIdEqualTo(id);
            feeDetailMapper.deleteByExample(example);
        }
        return null;
    }

    @Override
    public Integer deleteReceivableDetail(Integer id) throws Exception {
        LOGGER.info("ReceivableServiceImpl.deleteReceivableDetail params : {}, {}", id);
        if (null == id) {
            LOGGER.error("ReceivableServiceImpl.deleteReceivableDetail param id must not be null ");
            throw new IllegalArgumentException("id不能为空");
        }
        BmsReceivableFeeDetail detail = feeDetailMapper.selectByPrimaryKey(id);
        feeDetailMapper.deleteByPrimaryKey(id);
        return sumBillCost(detail.getBillId());
    }

    @Override
    public Integer deleteReceivableDetailTemp(Integer id) throws Exception {
        LOGGER.info("ReceivableServiceImpl.deleteReceivableDetailTemp params : {}, {}", id);
        if (null == id) {
            LOGGER.error("ReceivableServiceImpl.deleteReceivableDetailTemp param id must not be null ");
            throw new IllegalArgumentException("id不能为空");
        }
        return tempMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<SServiceOrderWithReceivable> selectConsignorName() throws Exception {
        return sOrderMapper.selectConsignorName();
    }

    @Override
    public Integer confirmProceed(Integer billId, String invoiceDateString, String payeeDateString, String username) throws Exception {
        LOGGER.info("ReceivableServiceImpl.confirmProceed params : {}, {}", billId, invoiceDateString, payeeDateString);
        if (null == billId) {
            LOGGER.error("ReceivableServiceImpl.confirmProceed param billId must not be null ");
            throw new IllegalArgumentException("账单id不能为空");
        }
        if (null == payeeDateString) {
            LOGGER.error("ReceivableServiceImpl.confirmProceed param date must not be null ");
            throw new IllegalArgumentException("收款日期不能为空");
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        BmsReceivableBill bill = new BmsReceivableBill();
        bill.setId(billId);
        bill.setPayeeDate(format.parse(payeeDateString));
        if (StringUtils.isNotBlank(invoiceDateString))
            bill.setInvoiceDate(format.parse(invoiceDateString));
        bill.setPayeeStatus(PayeeStatusEnum.FINISH_PAY.getValue());
        bill.setModifiedUser(username);
        billMapper.updateByPrimaryKeySelective(bill);
        //根据账单ID查询服务订单ID，如果客户订单下所有服务订单都收款则修改订单支付状态，否则不修改。
        // 根据账单获取所有服务订单id
        List<Long> sids = feeDetailMapper.queryServOrderId(bill.getId());
        // 根据账单获取所有订单id
        List<Long> oids = feeDetailMapper.queryOrderId(bill.getId());
        Set<Long> set = new HashSet();
        if (oids.size()>0) {
            oids.stream().forEach(oid -> {
                // 查出该订单下所有服务订单
                SServiceOrderExample example = new SServiceOrderExample();
                example.createCriteria().andCustomerOrderIdEqualTo(oid);
                List<SServiceOrder> sServiceOrders = sOrderMapper.selectByExample(example);
                if (sServiceOrders.size()>0) {
                    sServiceOrders.stream().forEach(s -> {
                        if (!sids.contains(s.getId())) {
                            // 判断服务订单id是否存在已付款账单中，'0'表示不存在
                            Integer isId = feeDetailMapper.queryIsServOrderId(s.getId());
                            if (isId == 0) {
                                set.add(oid);
                            }
                        }
                    });
                }
            });
        }else {
            LOGGER.error("ReceivableServiceImpl.confirmProceed oids  must not be null");
            throw new IllegalArgumentException("根据账单ID查询订单ID为空!");
        }
        // 移除有未付款的订单
        if (set.size()>0){
            set.stream().forEach(id ->{ oids.remove(id); });
        }
        // 批量更新订单支付状态
        if (oids.size()>0) {
            try {
                SOrderExample example = new SOrderExample();
                example.createCriteria().andIdIn(oids);
                SOrder order = new SOrder();
                order.setPayStatus(30);
                orderMapper.updateByExampleSelective(order, example);
            } catch (Exception e) {
                throw new IllegalArgumentException("更新订单支付状态失败!");
            }
        }
        return null;
    }

    @Override
    public void exportExcel(List orderIds, HttpServletRequest request, HttpServletResponse response) throws Exception {
        LOGGER.info("ReceivableServiceImpl.exportExcel params : {}, {}", orderIds);
        if (orderIds.size()<=0) {
            LOGGER.error("ReceivableServiceImpl.exportExcel param orderIds must not be null ");
            throw new IllegalArgumentException("orderIds不能为空");
        }
        List<SServiceOrderWithReceivable> list = feeDetailMapper.selectListDetailByBillIds(orderIds);
        if (list.size()<=0) {
            LOGGER.error("ReceivableServiceImpl.exportExcel data must not be null ");
            throw new IllegalArgumentException("账单明细为空！");
        }
        List listTitle = new ArrayList();
        listTitle.add("客户订单号");
        listTitle.add("服务订单号");
        listTitle.add("客户");
        listTitle.add("下单日期");
        listTitle.add("下单人");
        listTitle.add("所属部门");
        listTitle.add("发车人");
        listTitle.add("发车人电话");
        listTitle.add("发车地址");
        listTitle.add("收车人");
        listTitle.add("收车人电话");
        listTitle.add("收车地址");
        listTitle.add("起运地");
        listTitle.add("目的地");
        listTitle.add("品牌");
        listTitle.add("车系");
        listTitle.add("车架号");
        listTitle.add("数量");
        listTitle.add("订单价");
        listTitle.add("调整金额");
        listTitle.add("结算价");
        listTitle.add("状态");
        List<List> listData = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        list.stream().forEach(val ->{
            List data = new ArrayList();
            if (StringUtils.isNotBlank(val.getCustomerOrderCode()))
                data.add(val.getCustomerOrderCode());
            else data.add("");
            if (StringUtils.isNotBlank(val.getServiceOrderCode()))
                data.add(val.getServiceOrderCode());
            else data.add("");
            if (StringUtils.isNotBlank(val.getConsignorName()))
                data.add(val.getConsignorName());
            else data.add("");
            if (val.getCreateTime()!=null)
                data.add(format.format(val.getCreateTime()));
            else data.add("");
            if (StringUtils.isNotBlank(val.getRealName()))
                data.add(val.getRealName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDivisionName()))
                data.add(val.getDivisionName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartContact()))
                data.add(val.getDepartContact());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartPhone()))
                data.add(val.getDepartPhone());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartAddr()))
                data.add(val.getDepartAddr());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptContact()))
                data.add(val.getReceiptContact());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptPhone()))
                data.add(val.getReceiptPhone());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptAddr()))
                data.add(val.getReceiptAddr());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartProvinceName())&&StringUtils.isNotBlank(val.getDepartCityName()))
                data.add(val.getDepartProvinceName()+"-"+val.getDepartCityName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptProvinceName())&&StringUtils.isNotBlank(val.getReceiptCityName()))
                data.add(val.getReceiptProvinceName()+"-"+val.getReceiptCityName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getBrandName()))
                data.add(val.getBrandName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getVehicleName()))
                data.add(val.getVehicleName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getVin()))
                data.add(val.getVin());
            else data.add("");
            if (val.getAmount()!=null)
                data.add(val.getAmount());
            else data.add("");
            if (val.getSysCost()!=null)
                data.add(val.getSysCost().doubleValue());
            else data.add("");
            if (val.getAlterCost()!=null)
                data.add(val.getAlterCost().doubleValue());
            else data.add("");
            if (val.getSettleCost()!=null)
                data.add(val.getSettleCost().doubleValue());
            else data.add("");
            if (val.getStatus()!=null){
                data.add(val.getStatus()==10?"待接单": (val.getStatus()==30?"待支付":
                        (val.getStatus()==40?"执行中": (val.getStatus()==50?"已提车":
                                (val.getStatus()==60?"已发车": (val.getStatus()==70?"运输中":
                                        (val.getStatus()==80?"已交车": (val.getStatus()==90?"已完成":""))))))));
            }
            else data.add("");
            listData.add(data);
        });
        PoiUtil.exportExcel("应收账单详情", listTitle, listData, response);
    }

    @Override
    public void exportProceed(List orderIds, HttpServletRequest request, HttpServletResponse response) throws Exception {
        LOGGER.info("ReceivableServiceImpl.exportProceed params : {}, {}", orderIds);
        if (orderIds.size()<=0) {
            LOGGER.error("ReceivableServiceImpl.exportProceed param orderIds must not be null ");
            throw new IllegalArgumentException("orderIds不能为空");
        }
        List<SServiceOrderWithReceivable> list = feeDetailMapper.selectListDetailByBillIds(orderIds);
        if (list.size()<=0) {
            LOGGER.error("ReceivableServiceImpl.exportProceed data must not be null ");
            throw new IllegalArgumentException("账单明细为空！");
        }
        List listTitle = new ArrayList();
        listTitle.add("客户订单号");
        listTitle.add("服务订单号");
        listTitle.add("客户");
        listTitle.add("下单日期");
        listTitle.add("下单人");
        listTitle.add("所属部门");
        listTitle.add("发车人");
        listTitle.add("发车人电话");
        listTitle.add("发车地址");
        listTitle.add("收车人");
        listTitle.add("收车人电话");
        listTitle.add("收车地址");
        listTitle.add("起运地");
        listTitle.add("目的地");
        listTitle.add("品牌");
        listTitle.add("车系");
        listTitle.add("车架号");
        listTitle.add("数量");
        listTitle.add("订单价");
        listTitle.add("调整金额");
        listTitle.add("结算价");
        listTitle.add("状态");
        listTitle.add("运单号");
        listTitle.add("承运商");
        listTitle.add("采购价");
        List<List> listData = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        list.stream().forEach(val ->{
            List data = new ArrayList();
            if (StringUtils.isNotBlank(val.getCustomerOrderCode()))
                data.add(val.getCustomerOrderCode());
            else data.add("");
            if (StringUtils.isNotBlank(val.getServiceOrderCode()))
                data.add(val.getServiceOrderCode());
            else data.add("");
            if (StringUtils.isNotBlank(val.getConsignorName()))
                data.add(val.getConsignorName());
            else data.add("");
            if (val.getCreateTime()!=null)
                data.add(format.format(val.getCreateTime()));
            else data.add("");
            if (StringUtils.isNotBlank(val.getRealName()))
                data.add(val.getRealName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDivisionName()))
                data.add(val.getDivisionName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartContact()))
                data.add(val.getDepartContact());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartPhone()))
                data.add(val.getDepartPhone());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartAddr()))
                data.add(val.getDepartAddr());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptContact()))
                data.add(val.getReceiptContact());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptPhone()))
                data.add(val.getReceiptPhone());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptAddr()))
                data.add(val.getReceiptAddr());
            else data.add("");
            if (StringUtils.isNotBlank(val.getDepartProvinceName())&&StringUtils.isNotBlank(val.getDepartCityName()))
                data.add(val.getDepartProvinceName()+"-"+val.getDepartCityName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getReceiptProvinceName())&&StringUtils.isNotBlank(val.getReceiptCityName()))
                data.add(val.getReceiptProvinceName()+"-"+val.getReceiptCityName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getBrandName()))
                data.add(val.getBrandName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getVehicleName()))
                data.add(val.getVehicleName());
            else data.add("");
            if (StringUtils.isNotBlank(val.getVin()))
                data.add(val.getVin());
            else data.add("");
            if (val.getAmount()!=null)
                data.add(val.getAmount());
            else data.add("");
            if (val.getSysCost()!=null)
                data.add(val.getSysCost().doubleValue());
            else data.add("");
            if (val.getAlterCost()!=null)
                data.add(val.getAlterCost().doubleValue());
            else data.add("");
            if (val.getSettleCost()!=null)
                data.add(val.getSettleCost().doubleValue());
            else data.add("");
            if (val.getStatus()!=null){
                data.add(val.getStatus()==10?"待接单": (val.getStatus()==30?"待支付":
                        (val.getStatus()==40?"执行中": (val.getStatus()==50?"已提车":
                                (val.getStatus()==60?"已发车": (val.getStatus()==70?"运输中":
                                        (val.getStatus()==80?"已交车": (val.getStatus()==90?"已完成":""))))))));
            }
            else data.add("");
            if (StringUtils.isNotBlank(val.getWayCode()))
                data.add(val.getWayCode());
            else data.add("");
            if (StringUtils.isNotBlank(val.getPurCom()))
                data.add(val.getPurCom());
            else data.add("");
            if (val.getPurPrice()!=null)
                data.add(val.getPurPrice().doubleValue());
            else data.add("");
            listData.add(data);
        });
        PoiUtil.exportExcel("应收账单详情", listTitle, listData, response);
    }

    private void verificationForm(BindingResult br) {

        if (null == br) {
            LOGGER.error("ReceivableServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            LOGGER.error("DRouteServiceImpl.add error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    /**
     * 根据账单id更新账单金额
     * @param billId
     * @return
     * @throws Exception
     */
    public Integer sumBillCost(Integer billId) throws Exception{
        if (null == billId) {
            LOGGER.error("ReceivableServiceImpl.sumBillCost param billId must not be null ");
            throw new IllegalArgumentException("账单id不能为空");
        }
        SServiceOrderWithReceivable detail = feeDetailMapper.selectSumCost(billId);
        if (detail!=null){
            BmsReceivableBill bill = new BmsReceivableBill();
            bill.setId(billId);
            bill.setOrderCost(detail.getSysCost());
            bill.setAlterCost(detail.getAlterCost());
            bill.setSettleCost(detail.getSettleCost());
            bill.setGoodsSum(BigDecimal.valueOf(detail.getAmount()));
            billMapper.updateByPrimaryKeySelective(bill);
        }
        return null;
    }
}



